package fun.asgc.graalvmlab.lab2;

import fun.asgc.graalvmlab.lab2.compiler.AsgcCompiler;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.stream.Stream;

public class Main {
    private static final Person person;
    private static Method method;
    private static Class clazz;

    static {
        System.out.println("Main 静态代码块...");
        try {
            method = Person.class.getDeclaredMethod("say", String.class);

        // 动态生成的class，在static中生成，则能被graalvm识别
        AsgcCompiler compiler = new AsgcCompiler();
        String code = "package a.b;\n" +
                "public class Hello {\n" +
                "\tpublic void hello() {\n" +
                "\t\tSystem.out.println(\"hello\");\n" +
                "\t}\n" +
                "}\n";
        clazz = compiler.compile("a.b.Hello", code);
        } catch (Exception e) {
            System.out.println("获得方法失败!" + e.getMessage());
        }
        person = new Person("张三");
    }

    public static void main(String[] args) throws Exception {
        System.out.println("Hello Word! args:" + String.join(",", args));
        person.say("hello");
        System.out.println("reflect1--->");
        method.invoke(person, "123abc");
        System.out.println("reflect2--->");
        Method method1 = Person.class.getDeclaredMethod("say", String.class);
        method1.invoke(person, "234abc");
        System.out.println("reflect3--->");
        Constructor<Dog> constructor = Dog.class.getConstructor(String.class);
        Dog dog = constructor.newInstance("大黄");
        dog.shout();

        System.out.println("class gen--->");
//        AsgcCompiler compiler = new AsgcCompiler();
//        String code = "package a.b;\n" +
//                "public class Hello {\n" +
//                "\tpublic void hello() {\n" +
//                "\t\tSystem.out.println(\"hello\");\n" +
//                "\t}\n" +
//                "}\n";
//        Class clazz = compiler.compile("a.b.Hello", code);
//        Method method = Stream.of(clazz.getMethods()).filter(m -> m.getName().equals("hello")).findFirst().get();
//        Object instance = clazz.newInstance();
//        method.invoke(instance);
        Method method = Stream.of(clazz.getMethods()).filter(m -> m.getName().equals("hello")).findFirst().get();
        Object instance = clazz.newInstance();
        method.invoke(instance);
    }

}
